Skip to content

Fix/arbitrary failing on feature flag#1128

Closed
rajatdahal (razzat008) wants to merge 6 commits into
Devolutions:masterfrom
razzat008:fix/arbitrary_failing_on_feature_flag
Closed

Fix/arbitrary failing on feature flag#1128
rajatdahal (razzat008) wants to merge 6 commits into
Devolutions:masterfrom
razzat008:fix/arbitrary_failing_on_feature_flag

Conversation

@razzat008
Copy link
Copy Markdown

@razzat008 rajatdahal (razzat008) commented Feb 26, 2026

working on #1121

This commit adds conditional attribute, which implements the `Arbitrary`
trait when compiled with `--features arbitrary`; this is to ensure,
sucessful checks/builds for future fuzzing implementation
@razzat008
Copy link
Copy Markdown
Author

Benoît Cortier (@CBenoit)
Some structs(inside bitflags macro) needed manual implementation of the Arbitrary trait, so I'll push them too shortly.

Added conditional arbitrary for structs/enums that support it; files
related to this commit most probably won't require manual impl of the
Arbitrary trait.
Due to inter-dependency, most of the struct/enums had to be configured
…uence

The mannual impl for ChannelName follows the 8-bi null-terminated
sequence; and the mannual impl for LicenseExchangeSequence generates
arbitrary for all attributes except the license_cache
#cfg_attr for ChunkProcessor,StaticVirtualChannel and a constructor for
the StaticChannelSet(as it has TypeId which is populated by the
compiler)
@razzat008
Copy link
Copy Markdown
Author

I was not confident with some of the impls so I've added MIGHT NEED CHANGE for those parts.
Also, the StaticChannelSet had an attribute which used the TypeId which didn't implement the Arbitrary trait, so it just calls the constructor for now.

Mannual impls are done for:

  • LicenseExchangeSequence: the license_cache attribute had dyn trait
  • ChannelName: a valid null terminated sequence was required

@razzat008
Copy link
Copy Markdown
Author

The checks are passing for as of now:

cargo check -p ironrdp-connector --features arbitrary
cargo check -p ironrdp-pdu --features arbitrary

pub domain: Option<String>,
pub hardware_id: [u32; 4],
pub license_cache: Arc<dyn LicenseCache>,
pub _phantom: std::marker::PhantomData<u8>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why did you add this PhantomData?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially thought it was required for the dyn trait object to compile successfully, so I left it in there and forgot about it, even after the manual impl for LicenseExchangeSequence.
It compiles fine without it and isn't needed, my bad:))

Comment on lines +121 to +122
// MIGHT NEED CHANGE, currently it's not using arbitrary function
license_cache: Arc::new(NoopLicenseCache),
Copy link
Copy Markdown
Member

@CBenoit Benoît Cortier (CBenoit) Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is perfectly fine as we don’t provide any LicenseCache implementation as part of this crate. Implementers wishing to fuzz using their license cache should do so on their side.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noted

Copy link
Copy Markdown
Member

@CBenoit Benoît Cortier (CBenoit) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not entirely sure what the Arbitrary trait is meant to do in ironrdp-svc: we’re probably not going to deal with "arbitrary static virtual channels", so maybe a better way would be to manually implement the trait at some places more in ironrdp-connector 🤔

@razzat008
Copy link
Copy Markdown
Author

I understand, the structs in the ironrdp-svc crate were used in some other places which had to implement arbitrary, so without those checks wouldn't compile.
I will look into manual implementation for the connector.
Thanks

@glamberson
Copy link
Copy Markdown
Contributor

Hi rajatdahal (@razzat008),

Thanks for taking this on. The arbitrary feature is a meaningful unblocker for the fuzzing roadmap Benoît Cortier (@CBenoit) outlined in #1120 and the four sub-issues stacked under it.

I have been reading through the diff in preparation for picking up some of the structured-fuzzing follow-on work, and I wanted to consolidate the open items in one place so this PR has a clear path to land.

Outstanding technical items

  1. Architectural placement of Arbitrary in ironrdp-svc. Benoît Cortier (@CBenoit)'s last review suggested moving these impls into manual implementations in ironrdp-connector instead, since ironrdp-svc is unlikely to need fuzz support directly. This is the substantive directional change still pending.

  2. StaticChannelSet Arbitrary constructor fallback. The current Ok(StaticChannelSet::new()) approach produces only the empty channel set under fuzzing, which means the connector state machine never sees a populated channel set during structured fuzz runs. If the intent is to exercise channel-dependent code paths under fuzz, this would need to populate the set with some plausible channels. If not, leaving it as a documented limitation in the PR description is fine.

  3. Option<Arc<dyn LicenseCache>> using #[arbitrary(default)]. Same trade-off shape as item 2: license-cache-dependent paths never execute under fuzz with this approach. Worth recording the decision in the PR description either way.

  4. PhantomData in license_exchange.rs. You already acknowledged in the thread that this is unnecessary. Worth removing in the next push.

  5. The // MIGHT NEED CHANGE markers. Useful to keep visible during review, but should be resolved before merge.

  6. Feature flag wiring for no_std + alloc. The umbrella in Fix arbitrary feature flag plumbing so it compiles #1121 specifies the wiring should be arbitrary = ["alloc", "dep:arbitrary"] for crates that support no_std + alloc. The current wiring in ironrdp-connector/Cargo.toml is arbitrary = ["dep:arbitrary", "ironrdp-pdu/arbitrary"], which omits the alloc feature dependency. Worth checking whether ironrdp-connector actually supports no_std + alloc (it looks std-only on a quick read) and adjusting the feature line if needed.

  7. Rebase against master and cargo fmt. The branch is in CONFLICTING state due to drift since February, and the format check is failing. These would need to be cleared.

Coordination

If you are still actively working on this and just bandwidth-limited, that is fine on my side. If you would welcome a collaborator on the architectural reshape in item 1 and the rebase in item 7 while you stay as the main author, I can chip in there. Either way works for me. The structured-fuzzing infrastructure work in #1122 and #1124 is downstream of this PR landing.

Let me know what would be most useful.

@glamberson
Copy link
Copy Markdown
Contributor

Hi rajatdahal (@razzat008),

I went ahead and filed #1272 to address #1121 directly. The downstream fuzzing work in #1122 through #1124 was blocked on this landing, and the 2026-05-11 ping here did not get a response, so I treated the path as clear to step in.

Your exploration in this PR was the starting point. The decisions in #1272 about the ChannelName manual impl shape, the Arc<dyn LicenseCache> trade-off, the StaticChannelSet skip, and the feature-cascade wiring all build on the questions you and Benoît Cortier (@CBenoit) raised in this thread. Thanks for putting the original work in.

@CBenoit
Copy link
Copy Markdown
Member

Closing this PR since #1272 was merged earlier today.

Thank you for the initial exploration!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants